﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
		<title>Authorization</title>
		<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
		<style type="text/css">
.auto-style1 {
	font-weight: bold;
}
</style>
	</head>

	<body>

		<div class="document-contents">

			<h3 id="DocIntroduction">Introduction</h3>
			<p>Almost all enterprise applications use authorization in some level. 
Authorization is used to check if a user is allowed to perform some specific 
operation in the application. ASP.NET Boilerplate defines a <strong>permission
based</strong> infrastructure to implement authorization.</p>
			<div class="bs-callout bs-callout-warning">
				<h4>About IPermissionChecker</h4>
				<p>Authorization system uses <strong>IPermissionChecker</strong> to check 
permissions. While you can 
implement it in your own way, it's fully implemented in <strong>module-zero</strong> 
project. If it's not implemented, NullPermissionChecker is used which grants all 
permissions to everyone.</p>
			</div>

			<h3 id="DocDefinePermission">Defining Permissions</h3>
			<p>A unique <strong>permission </strong>is defined for each operation needed to be authorized. We should define a permission before use it. ASP.NET Boilerplate is designed 
to be 
				<a href="/Pages/Documents/Module-System">modular</a>. So, different modules can have different 
permissions. A module should 
create a class derived from <strong>AuthorizationProvider </strong>in order to define it's 
permissions. 
An example authorization provider is shown below:</p>
			<pre lang="cs">public class MyAuthorizationProvider : <strong>AuthorizationProvider</strong>
{
    public override void SetPermissions(IPermissionDefinitionContext context)
    {
        var administration = context.<strong>CreatePermission</strong>(&quot;Administration&quot;);

        var userManagement = administration.<strong>CreateChildPermission</strong>(&quot;Administration.UserManagement&quot;);
        userManagement.<strong>CreateChildPermission</strong>(&quot;Administration.UserManagement.CreateUser&quot;);

        var roleManagement = administration.<strong>CreateChildPermission</strong>(&quot;Administration.RoleManagement&quot;);
    }
}
			</pre>
			<p>
				<strong>IPermissionDefinitionContext</strong> has methods to get and create 
permissions.</p>
			<p>A permission have some properties to define it:</p>
			<ul>
				<li>
					<strong>Name</strong>: a system-wide <strong>unique</strong> name. It's 
	good idea to define a const string for a permission name instead of a magic 
	string. We prefer to use . (dot) notation for hierarchical names but it's 
	not required. You can set any name you like. Only rule is that it must be 
	unique.</li>
				<li>
					<strong>Display name</strong>: A localizable string that can be used to 
	show permission, later in UI.</li>
				<li>
					<strong>Description</strong>: A localizable string that can be used to 
	show definition of the permission, later in UI.</li>
				<li>
					<strong>MultiTenancySides</strong>: For multi-tenant application, a 
	permission can be used by tenants or the host. This is a <strong>Flags
					</strong>enumeration and thus a permission can be used in both sides.</li>
				<li>
					<strong>featureDependency</strong>: Can be used to declare a dependency to
					<a href="/Pages/Documents/Feature-Management">features</a>. Thus, this 
	permission can be granted only if feature dependency is satisfied. It waits for an object implements IFeatureDependency. Default implementation is the SimpleFeatureDependency class. Example usage: <code>new SimpleFeatureDependency("MyFeatureName")</code></li>
			</ul>
			<p>A permission can have a parent and child permissions. While this does not 
effect permission checking, it may help to group permissions in UI.</p>
			<p>After creating an authorization provider, we should register it in PreInitialize 
method of our module:</p>
			<pre lang="cs"><strong>Configuration.Authorization.Providers.Add</strong>&lt;MyAuthorizationProvider&gt;();</pre>
			<p>Authorization providers are registered to <a href="/Pages/Documents/Dependency-Injection">dependency injection</a> 
automatically. So, an authorization provider can inject any dependency (like a 
repository) to build permission definitions using some other sources.</p>

			<h3 id="DocCheckPermission">Checking Permissions</h3>
			<h4 id="DocUsingAbpAuthorize">Using AbpAuthorize Attribute</h4>
			<p>
				<strong>AbpAuthorize</strong> (<strong>AbpMvcAuthorize</strong> for MVC Controllers and 
				<strong>AbpApiAuthorize</strong> for Web API Controllers) attribute is the easiest and most common way of checking permissions. Consider&nbsp;the 
				<a href="/Pages/Documents/Application-Services">application service</a> method shown below:</p>
			<pre lang="cs"><strong>[AbpAuthorize(&quot;Administration.UserManagement.CreateUser&quot;)]</strong>
public void CreateUser(CreateUserInput input)
{
    //A user can not execute this method if he is not granted for "Administration.UserManagement.CreateUser" permission.
}</pre>
			<p>CreateUser method can not be called by a user who is not granted for permission "<em>Administration.UserManagement.CreateUser</em>".</p>
			<p>AbpAuthorize attribute also checks if current user is logged in (using
				<a href="/Pages/Documents/Abp-Session">IAbpSession.UserId</a>). So, if we declare an 
AbpAuthorize for a method, it only checks for login:</p>
			<pre lang="cs"><strong>[AbpAuthorize]</strong>
public void SomeMethod(SomeMethodInput input)
{
    //A user can not execute this method if he did not login.
}</pre>
			<h5>AbpAuthorize attribute notes</h5>
			<p>ASP.NET Boilerplate uses power of dynamic method interception for 
authorization. So, there is some restrictions for the methods use AbpAuthorize 
attribute.</p>
			<ul>
				<li>Can not use it for private methods.</li>
				<li>Can not use it for static methods.</li>
				<li>Can not use it for methods of a non-injected class (We must use
					<a href="/Pages/Documents/Dependency-Injection">dependency injection</a>).</li>
			</ul>
			<p>Also,</p>
			<ul>
				<li>Can use it for any <strong>public</strong> method if the method is called over an 
					<strong>interface </strong>(like Application Services used over interface).</li>
				<li>A method should be <strong>virtual</strong> if it's called directly 
	from class reference (like ASP.NET MVC or Web API Controllers).</li>
				<li>A method should be <strong>virtual</strong> if it's <strong>protected</strong>.</li>
			</ul>
			<p>
				<b>N</b><span class="auto-style1">otice</span>: There are four 
				types of authorize attributes:</p>
			<ul>
				<li>In an application 
service (application layer), we use <strong>Abp.Authorization.AbpAuthorize</strong> 
				attribute.</li>
				<li>In an MVC controller (web layer), we use <strong>Abp.Web.Mvc.Authorization.AbpMvcAuthorize</strong> 
				attribute.</li>
				<li>In ASP.NET Web API, we 
use <strong>Abp.WebApi.Authorization.AbpApiAuthorize</strong> attribute.</li>
				<li>In ASP.NET Core, we use <strong>
				Abp.AspNetCore.Mvc.Authorization.AbpMvcAuthorize</strong> 
				attribute.</li>
			</ul>
			<p>This 
difference comes from inheritance. In application layer it's 
completely ASP.NET Boilerplate's implementation and does not extend any class. 
			But, int MVC and Web API, it inherits from Authorize attributes of 
			those frameworks.</p>
			<h5>Suppress Authorization</h5>
			<p>You can disable authorization for a method/class by adding
			<strong>AbpAllowAnonymous</strong> attribute to aplication services. 
			Use <strong>AllowAnonymous</strong> for MVC, Web API and ASP.NET 
			Core Controllers, which are native attributes of these frameworks.</p>
			<h4 id="DocUsingPermissionChecker">Using IPermissionChecker</h4>
			<p>While AbpAuthorize attribute pretty enough for most cases, there must be 
situations we should check for a permission in a method body. We can inject and 
use <strong>IPermissionChecker</strong> for that as shown in the example below:</p>
			<pre lang="cs">public void CreateUser(CreateOrUpdateUserInput input)
{
    if (!<strong>PermissionChecker.IsGranted("Administration.UserManagement.CreateUser")</strong>)
    {
        throw new AbpAuthorizationException("You are not authorized to create user!");
    }

    //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.
}</pre>
			<p>Surely, you can code any logic since <strong>IsGranted</strong> simply 
returns true or false (It has Async version also). If you simply check a 
permission and throw an exception as shown above, you can use the <strong>
Authorize</strong> method:</p>
			<pre lang="cs">public void CreateUser(CreateOrUpdateUserInput input)
{
    <strong>PermissionChecker.Authorize("Administration.UserManagement.CreateUser");</strong>

    //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.
}</pre>
			<p>Since authorization is widely used, <strong>
ApplicationService</strong> and some common base classes inject and define PermissionChecker 
property. Thus, permission checker can be used without injecting in application 
service classes.</p>
			<h4>In Razor Views</h4>
			<p>Base view class defines IsGranted method to check if current user has a 
	permission. Thus, we can conditionally render the view. Example:</p>
			<pre lang="xml">@if (<strong>IsGranted("Administration.UserManagement.CreateUser")</strong>)
{
    &lt;button id=&quot;CreateNewUserButton&quot; class=&quot;btn btn-primary&quot;&gt;&lt;i class=&quot;fa fa-plus&quot;&gt;&lt;/i&gt; @L(&quot;CreateNewUser&quot;)&lt;/button&gt;
}</pre>

			<h4>Client Side (Javascript)</h4>

			<p>In the client side, we can use API defined in <strong>abp.auth</strong> 
namespace. In most case, we need to check if current user has a specific 
permission (with permission name). Example:</p>
			<pre lang="js">abp.auth.isGranted('Administration.UserManagement.CreateUser');</pre>

			<p>You can also use <strong>abp.auth.grantedPermissions</strong> to get all 
granted permissions or <strong>abp.auth.allPermissions</strong> to get all 
available permission names in the application. Check <strong>abp.auth</strong> 
namespace on runtime for others.</p>

			<h3>Permission Manager</h3>
			<p>We may need to definitions of permission. <strong>IPermissionManager</strong> 
can be <a href="/Pages/Documents/Dependency-Injection">injected</a> and used in 
that case. </p>

		</div>

	</body>

</html>
